//Nathan Popham
//4003-573-01: Procedural Shading
//Lab 2
//
//Strauss lighting model
// may I just say that specular sucks

varying vec3 N, V, pos;

uniform int NumLights;
uniform float m;
uniform float s;
uniform float t;

float sqr (float x) { return x * x; }


/*
 *  Fresnel equation
 */
float F (float angle)
{
    float kf = 1.12;
    float x = angle / (3.14159/2.0);
    return            
    ((1.0 / sqr(x - kf)) - (1.0 / sqr(kf))) /
    ((1.0 / sqr(1.0 - kf)) - (1.0 / sqr(kf)));
}


/*
 *  Whatever the G function is
 */
float G (float angle)
{
    float kg = 1.01;
    float x = angle / (3.14159/2.0);

    return
    ((1.0 / sqr(1.0 - kg)) - (1.0 / sqr(x - kg))) /
    ((1.0 / sqr(1.0 - kg)) - (1.0 / sqr(kg)));
}

void main()
{
    float Ka = 0.0;     


    float kj = 0.1;
    vec3 Nn = normalize(N); 
    float d = (1.0 - m*s);
    float h = 3.0 / (1.0 - s);
    float rd = (1.0 - s * s * s) * (1.0 - t); 
    float rn = 1.0 - t - rd;

    vec3 Qa = vec3(rd * gl_FrontMaterial.ambient);
    vec3 Qd = vec3(0.0, 0.0, 0.0);
    vec3 Qs = vec3(0.0, 0.0, 0.0);

    for(int i = 0; i < NumLights; i++)
    {
        vec3 Ln;

        if(gl_LightSource[i].position[3] == 0.0)        
            Ln = normalize(vec3((gl_LightSource[i].position)));
        else 
            Ln = normalize(vec3(gl_LightSource[i].position) - pos);
        
        float NdotL = max(dot(Nn, Ln), 0.0);
        
        if(NdotL > 0.0)
        {
            Qd += vec3(gl_LightSource[i].diffuse * NdotL * d * rd * gl_FrontMaterial.diffuse);

            vec3 H = normalize(Ln - 2.0*NdotL*Nn);
            float HdotV = max(dot(H, -V), 0.0);
            float NdotV = max(dot(Nn,-V), 0.0);
            float j = F(NdotL) * G(NdotL) * G(NdotV);
            float rj = min(1.0, rn + (rn + kj)*j);
            float rs = pow(HdotV, h) * rj;
            
            vec3 CspecDiff = m * (1.0 - F(NdotL)) * vec3(gl_FrontMaterial.specular - gl_LightSource[i].specular);

            vec3 Cspec = vec3(gl_LightSource[i].specular) - CspecDiff;

            //if(Cspec < (0.0, 0.0, 0.0))
            //    Cspec = Cl - CspecDiff; 
            
            Qs += vec3(gl_LightSource[i].specular * rs);
            //Qs += Cspec * rs;
        }
    }  
    gl_FragColor = vec4( Qs + Qd + Ka*Qa, 1.0);
} 
